Waterfall Model
Inremental Development
Reuse-Oriented Sofware Engineering
Extreme Programming
Scrum
C-facing reqs | D-facing reqs |
---|---|
|
|
git blame
exists for a reason. Git is good.
Class diagrams (static): most common type of diagram, shows the entites within a system and their relations. Obviously most suited to OOP.
Activity Diagrams (behaviour): kinda like a flowchart really. Note that decision doesn't have anything written inside it.
Use case diagrams: how different events interact with other events.
Sequence Diagrams: to show temporal interaction -- how a system's interactions go over time.
name:Object
for a named object, :Object
for an anonymous object, and name
for a named unknown class.
Very few projects succeed, why is this so? Well, there are a multitude of reasons, amongst them poor planning, requirements changing too much, high turnover, unrealistic deadlines, poor testing, and so on and so forth.
Project management is essential to making sure constraints are kept, to
Team success depends on three generic factors:
People are motivated through satisfaction of their needs (something something heirarchy of needs).
Heirarchy is still important. Should the PM be the Tech lead? Or should it be someone else? Who will interact with stakeholders? How do we integrate people who are not in the same location? How can knowledge be shared?
Group organisation can be informal or heirarchical:
A cohesive team can establish their own quality standards, and actually follow them. Individuals will learn from and support each other, and people tend to work better.
Risks can be grouped into what areas they affect. Project risks affect the schedule or resources of the entire project. Product risks affect the final quality of the product. Business risks affect the organisation. Some risks can fall into multiple categories.
Project Risks include staff turnover, management change, hardware unavailability, requirements change, etc.
Prduct Risks include tool/library underperformance, the aforementioned requirements change, specification delays, size/complexity underestimates, etc.
Business Risks include technology changes and deprecation, product competition, etc.
There can be even finer category groups: such as Technology Risks, People Risks, Organisational Risks, Tool Risks, Requirements Risks and Estimation Risks.
Consider each risk and its severity, this can then be grouped and prioritised
For example, you could have a rating Insignificant/Tolerable/Serious/Catastrophic.
Once you have a prioritised risk list, a contingency plan for each risk must be made. First is avoidance: aim to reduce the chance of the risk even becoming reality, then comes minimisation: reducing damage if it goes wrong, and finally contingency plans: what to do if risk does occur.
This all goes into a risk assessment / risk register, which can be a docuemnt, or on a management platform, but somewhere accessible to management.
The planning documents of a project should communicate all ideas, contingencies, organisation, etc to both the developers and the stakeholder.
Planning has three stages: (1) Proposal / pitch / bidding phase, (2) startup phase, and (3) periodic planning.
Scheduling is done through Gantt Charts, and critical path analysis algorithms for scheduing which tasks go first.
Estimation of costs and schedule however is really very easier said than done,
Success is measured against how well the project meets the spec and existing expectations.
class Race {
public Race createRace() {
Frame frame1 = new Frame();
Wheel frontWheel1 = new Wheel();
Wheel rearWheel1 = new Wheel();
Bike bike1 = new Bike(frame1, frontWheel1, rearWheel1);
// repeat for every single other bike in the race...
}
class TourDeMartinique extends Race {
public Race createRace() {
// we need regulation bikes
// so we have to go through the whole rigamarole again of bike creation...
Frame frame1 = new RegulationFrameEx007();
Wheel frontWheel1 = new RegulationWheel1800F();
Wheel rearWheel1 = new RegulationWheel1800F();
Bike bike1 = new Bike(frame1, frontWheel1, rearWheel1);
// ...
}
it makes things even worse. Worse still, if we need to change something, then we would have to update the whole thing, which is error prone.
class TourDeMartinique extends Race {
Frame createFrame() { return new RegulationFrameEx007(); }
Wheel createWheel() { return new RegulationWheel1800F(); }
Bike createBike(Frame frame, Wheel front, Wheel back) {
return new Bike(frame, front, back);
}
}
especially helpful if these common method signatures are implemented in the Race class.
class BicycleFactory {
Frame createFrame() { ... }
Wheel createWheel() { ... }
Bike createBike(Frame frame, Wheel front, Wheel back) { ... }
Bike createDefaultBike() { ... }
// etc.
}
build
call.
abstract class HouseBuilder {
abstract void buildWindows();
abstract void buildDoors();
abstract void buildWalls();
abstract void buildRooms();
}
@Builder
)
class Bike {
Object clone() { ... }
// ...
}
class Race {
Bike prototye;
public Race(Bike prototype) {
this.prototype = prototype;
}
public Race createRace() {
Bike b1 = (Bike) prototype.clone();
//...
}
}
public interface Graphic {
void draw();
}
public class ImageProxy implements Graphic {
private String fileName;
private Image content;
public ImageProxy(String fileName) {
this.fileName = fileName;
content = null;
}
public void draw() {
// only load the content when it is needed
if (content == null) content = new Image(fileName);
// the actual image class will have a draw function
content.draw();
}
}
Message
class, for each platform we would have to subcass: FacebookMessage
, TwitterMessage
, DiscordMessage
, etc, etc.
@Data
type things you see in Java.
Suppose we have this NPC:
class Orc {
String name;
int health;
Weapon weapon;
NPCAI style;
Map texture;
// methods...
}
But the texture map is huge, because this is a really detailed game. If every orc has its own copy, we can't store many of them. But this texture is common to all orcs (as well as a few other things), so might as well split this into
class OrcData {
static NPCAI style;
static Map texture;
static Weapon weapon;
}
class Orc {
String name;
int health;
OrcData data;
}
And so now we only store one copy of OrcData
.
Iterator
so we can do for (Object i : listOfObjects) { ... }
The example given is an art program
public class Canvas {
private int[][] colours;
public Canvas(int x, int y) {
colours = new int[x][y];
}
public void setPixel(int x, int y, int col) {
colours[x][y] = col;
}
public Snapshot makeSnapshot() {
return new Snapshot(this, colours);
}
}
public class Snapshot {
private Canvas canvas;
private int[][] colours;
public Snapshot(Canvas canvas, int[][] colours) {
this.canvas = canvas; // maintain refererence to existing canvas object
this.colours = colours;
}
public void restore() {
for (int i = 0; i < colours.length; i++) {
for (int j = 0; j < colours[0].length; j++) {
canvas.setPixel(i, j, colours[i][j]);
}
}
}
}
public class Caretaker {
List<Snapshot> history;
public Caretaker() {
history = new ArrayList<Snapshot>();
}
public void addEntry(Snapshot s) {
history.add(s);
}
public void restore() {
Snapshot s = history.get(history.size()-1);
s.restore();
}
}
We can use metrics to evaluate a UI - such as the ratio of success to failure, time to complete a task, number of errors a user makes, or the number of times a user expresses frustration (windows 10 settings app) or satisfaction.
Dependability is the trustworthiness of a computer system such that reliance can be justifiably placed on the service it delivers.
That was -- that was more of a word salad than I expected. Dependability is the trustworthiness of a computer system and the services it provides
might be better?